// 七、TS中的类

// 1.基础

// class Point {
//   public x: number
//   public y: number
//   constructor(x: number, y: number) {
//     this.x = x
//     this.y = y
//   }
//   public getPosition() {
//     return `(${this.x},${this.y})`
//   }
// }
// const point = new Point(1, 2)
// console.log(point);

// class Parent {
//   public name: string
//   constructor(name: string) {
//     this.name = name
//   }
// }

// class Child extends Parent {
//   constructor(name: string) {
//     super(name)
//   }
// }

// 2.修饰符

// 2.1 public 公共 实例可以访问的方法、属性
// 2.2 private 私有
// 2.3 protected 受保护 可以在继承的子类访问,拿不到属性，能拿到方法
// protected可以修饰constructor，这个类不能用来创建实例，只能被子类继承
// class Parent {
//   protected age: number
//   constructor(age: number) {
//     this.age = age
//   }
//   protected getAge() {
//     return this.age
//   }
// }
// const p = new Parent(18)
// console.log(p.age);
// console.log(Parent.age);
// class Child extends Parent {
//   constructor(age: number) {
//     super(age)
//     // console.log(super.age);
//     console.log(super.getAge());
//   }
// }

// 2.4 readonly 只读

// class UserInfo {
//   public readonly name: string
//   constructor(name:string){
//     this.name = name
//   }
// }
// const userInfo = new UserInfo('lison')
// console.log(userInfo);
// userInfo.name='jhaha'

// 3.参数属性 修饰符修饰constructor的参数
//  class A{
//    constructor(private name:string){

//    }
//  }

//  const a1 = new A('lp')
//  console.log(a1.name);

// 4.静态属性
// class Parent {
//   private static age: number = 18
//   public static getAge() {
//     return Parent.age
//   }
//   constructor() {

//   }
// }
// const p = new Parent()
// console.log(p.age);
// console.log(Parent.age);

// 5.可选类属性
//6.取值器,存值器
// class Info {
//   public name: string
//   public age?: number
//   private _infoStr: string
//   constructor(name: string, age?: number, public sex?: string) {
//     this.name = name
//     this.age = age
//   }
//   get infoStr() {
//     return this._infoStr
//   }
//   set infoStr(value) {
//     console.log(value);
//     this._infoStr = value
//   }
// }
// const info1 = new Info('lp')
// console.log(info1);
// const info3 = new Info('lp',18)
// console.log(info3);
// const info4 = new Info('lp', 18, 'man')
// info4.infoStr = 'lplplplpl'
// console.log(info4);

// 7. 抽象类 一般用于被继承，不用来创建实例

// abstract class People{
//   constructor(public name:string){}
//     public abstract printName():void
// }
// // const p1 = new People()
// class Man extends People{
//   constructor(name:string){
//     super(name)
//     this.name = name
//   }
//   printName(){
//     console.log(this.name);
//   }
// }
// const m = new Man('lp')
// m.printName()

// abstract不仅能标记类和类中的方法，还能标记类中定义的属性和存取器

// abstract class People{
//   public abstract _name:string
//   abstract get insideName():string
//   abstract set insideName(value:string)
// }
// class P extends People{
//   public _name:string
//   public insideName:string
// }

// 8.实例属性

// class People {
//   constructor(public name: string) { }
// }
// let p: People = new People('lison')
// class Animal{
//   constructor(public name: string) { }
// }
// p = new Animal('haha')



// 补充

// 类的接口
interface FoodInterface {
  type: string
}
class FoodClass implements FoodInterface {
  public type: string
}

// 接口继承类

class A {
  protected name: string
}
interface I extends A {
}
class B extends A implements I {
  // protected 属性，只能在子类中访问
  public name: string
}


// 泛型中使用类
const create = <T>(c: { new(): T}):T=>{
  return new c()
}
class Info{
  public age:number
  constructor(){
    this.age=18
  }
}
console.log(create<Info>(Info));
console.log(create<Info>(Info).age);